package com.jccfc.iMessage.impl;

import com.jccfc.common.MessageUtil;
import com.jccfc.domain.email.MyAuthenricator;
import com.jccfc.iMessage.IMessage;
import com.jccfc.iMessageFactory.ParentMessageFactory;
import com.jccfc.iMessageTo.IMessageTo;
import com.jccfc.iMessageTo.impl.EmailMessageTo;
import com.sun.mail.util.MailSSLSocketFactory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.*;

/**
 * @Auther: qym
 * @Date: 2021/1/11 09:51
 * @Description: 发送邮件信息的对象类
 */
public class EmailMessage implements IMessage {

    //日志打印
    private Logger logger = LoggerFactory.getLogger(EmailMessage.class);

    //服务器
    private String mailHost = null;
    //端口
    private String mailPort = null;
    //协议
    private String mailProtocol = null;
    //发送 用户
    private String sender_username = null;
    //发送 密码
    private String sender_password = null;

    public EmailMessage() {
        //初始化参数
        init();
    }

    @Override
    public boolean sendMessage(IMessageTo iMessageTo) {
        //对数据进行校验
        boolean pass = MessageUtil.isPass(iMessageTo, EmailMessageTo.class);
        if (!pass) {
            logger.error("消息发送失败,传入参数类型不正确或者为null");
            return false;
        }
        //转化为具体的数据对象
        EmailMessageTo emailMessageTo = MessageUtil.downcast(iMessageTo, EmailMessageTo.class);
        //发送email
        boolean b = sendEmailMessage(emailMessageTo);
        return b;
    }

    /**
     * @Auther: qym
     * @Description: 具体发送email逻辑
     * @Param:
     * @Return:
     * @Date: 2021/1/11 11:08
     */
    private boolean sendEmailMessage(EmailMessageTo emailMessageTo) {

        Properties prop = new Properties();
        // 协议
        prop.setProperty("mail.transport.protocol", mailProtocol);
        // 服务器
        prop.setProperty("mail.smtp.host", mailHost);
        //端口
        prop.setProperty("mail.smtp.port", mailPort);
        //使用smtp身份验证
        prop.setProperty("mail.smtp.auth", "true");

        // 使用SSL，企业邮箱必需！
        // 开启安全协议
        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
        } catch (GeneralSecurityException e) {
            logger.error("开启SSL加密异常！" + e);
            return false;
        }
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);
        //创建session连接
        Session session = Session.getDefaultInstance(prop, new MyAuthenricator(sender_username, sender_password));
        // 开启DEBUG模式,在控制台中或日志中有日志信息显示，也就是可以从控制台中看一下服务器的响应信息；
        session.setDebug(true);
        MimeMessage message = new MimeMessage(session);
        try {
            InternetAddress from = null;
            if (StringUtils.isNotBlank(emailMessageTo.getSender_nickName())) {
                from = new InternetAddress(MimeUtility.encodeWord(emailMessageTo.getSender_nickName())
                        + "<" + sender_username + ">");
            } else {
                from = new InternetAddress(MimeUtility.encodeWord(emailMessageTo.getSender_nickName()));
            }
            message.setFrom(from);
            //如果收件人为空 不发送邮件
            if (StringUtils.isBlank(emailMessageTo.getReceiveUser())) {
                return false;
            }
            //替换收件人的分隔符（防止中文下产生无法分割成收件人数组的'，'替换成','）
            String rescivers = emailMessageTo.getReceiveUser().replaceAll("，", ",");
            //rescivers切割出收件人数组
            String[] arr = rescivers.split(",");
            //rescivers校验非空 所以 arr.length>0
            Address[] address = new Address[arr.length];
            for (int i = 0; i < arr.length; i++) {
                address[i] = new InternetAddress(arr[i]);
            }
            message.setRecipients(Message.RecipientType.TO, address);
            //发送时间
            message.setSentDate(new Date());
            //邮件主题
            message.setSubject(emailMessageTo.getSubject());
            // 向multipart对象中添加邮件的各个部分内容，包括文本内容和附件
            Multipart multipart = new MimeMultipart();
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setContent(emailMessageTo.getSendHtml(), "text/html;charset=UTF-8");
            multipart.addBodyPart(contentPart);
            //附件操作 附件列表
            if (emailMessageTo.getFilePath() != null && emailMessageTo.getFilePath().size() > 0) {
                for (String filename : emailMessageTo.getFilePath()) {
                    BodyPart attachmentBodyPart = new MimeBodyPart();
                    DataSource dataSource = new FileDataSource(filename);
                    attachmentBodyPart.setDataHandler(new DataHandler(dataSource));
                    // MimeUtility.encodeWord可以避免文件名乱码
                    attachmentBodyPart.setFileName(MimeUtility.encodeWord(dataSource.getName()));
                    multipart.addBodyPart(attachmentBodyPart);
                }
                // 移走集合中的所有元素
                emailMessageTo.getFilePath().clear();
            }
            //附件操作 附件的数据流
            if (emailMessageTo.getMaps() != null && emailMessageTo.getMaps().size() > 0) {
                Set<Map.Entry<String, InputStream>> entrySet = emailMessageTo.getMaps().entrySet();
                Iterator<Map.Entry<String, InputStream>> iterator = entrySet.iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, InputStream> entry = iterator.next();
                    MimeBodyPart fileBody = new MimeBodyPart();
                    DataSource source = new ByteArrayDataSource(entry.getValue(), "application/msexcel");
                    fileBody.setDataHandler(new DataHandler(source));
                    String fileName = entry.getKey();
                    fileBody.setFileName(MimeUtility.encodeText(fileName));
                    multipart.addBodyPart(fileBody);
                    if (entry.getValue() != null) {
                        entry.getValue().close();
                    }
                }
            }
            // 将multipart对象放到message中
            message.setContent(multipart);
            // 保存邮件
            message.saveChanges();
            //ssl发送
            Transport.send(message, address);
            logger.info(address.toString() + "send success!");
        } catch (Exception e) {
            logger.error("发送邮件异常:{}", e);
            return false;
        }
        return true;
    }

    @Override
    public boolean sendMessage(List<IMessageTo> iMessageTos) {
        return false;
    }

    @Override
    public boolean sendScheduleMessage(IMessageTo iMessageTo) {
        return false;
    }

    @Override
    public boolean sendScheduleMessage(List<IMessageTo> iMessageTos) {
        return false;
    }

    @Override
    public void init() {
        //初始化 发送email所需配置
        mailHost = ParentMessageFactory.getPropertie("email.mailHost");
        mailPort = ParentMessageFactory.getPropertie("email.port");
        mailProtocol = ParentMessageFactory.getPropertie("email.protocal");
        sender_username = ParentMessageFactory.getPropertie("email.sendEmail");
        sender_password = ParentMessageFactory.getPropertie("email.sendPassword");
    }

}
